package com.ly.mpayment.rest.up.huarongxunfang;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.ly.mpayment.core.util.*;
import com.ly.mpayment.persist.entity.UpOrder;
import com.ly.mpayment.persist.entity.UpShopInfo;
import com.ly.mpayment.persist.service.downrechargeflow.IDownRechargeFlowService;
import com.ly.mpayment.persist.service.downshopinfo.IDownShopInfoService;
import com.ly.mpayment.persist.service.uporder.IUporderService;
import com.ly.mpayment.persist.service.upshopinfo.IUpShopInfoService;
import com.ly.mpayment.rest.recharge.RechargeRest;
import org.apache.log4j.Logger;
import org.mortbay.util.MultiMap;
import org.mortbay.util.UrlEncoded;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

@Component
@Path("huarongxunfang")
public class HuaRongRest {

	Logger logger = Logger.getLogger(HuaRongRest.class);


	@Autowired
	IUporderService upOrderService;

	@Autowired
	private ThreadPoolTaskExecutor taskExecutor;

	@Autowired
	IDownRechargeFlowService flowService;

	@Autowired
	IDownShopInfoService shopService;

	@Autowired
	IUpShopInfoService upShopInfoService;

	/**
	 */
	@Path("callBack")
	@POST
	public synchronized String callBack(@RequestBody String body){
		logger.info("huarong_callBack:"+body);
		if(!StringUtils.isBlank(body)){
			JSONObject json = JSONObject.parseObject(body);
			UpOrder order = upOrderService.findById(json.getString("customer_order_no"));
		 	if(order == null){
		 		return "failt";
			}
			UpShopInfo upShopInfo = this.upShopInfoService.findByUserId(order.getUserOrder().getUseruuid());
			if(upShopInfo == null){
				return "failt";
			}
			try {
				//if(!sign.equals(StringSort.sign(upShopInfo.getUpkey(),StringSort.doSignKeyValue(json)))){
				//	logger.info("签名错误:"+order.getUpphonenum());
				//	return "sign_error";
				//}
				if (order != null && json.getString("order_status").equals("success") && order.getStatus() == Config.status[0]) {
					order.setRemark(json.containsKey("order_status") && !StringUtils.isBlank(json.getString("order_status")) ?
							json.getString("order_status") : json.getString("errmsg"));
					RechargeRest.successUpOrder.add(order);
					return "success";

				}else if(order != null && order.getStatus() == Config.status[0] && (json.getString("order_status").equals("fail"))){
					order.setRemark(json.getString("order_status"));
					RechargeRest.failtUpOrder.add(order);
					return "success";
				}else{
					logger.info("huarong_not_found_order:" + (order == null ? " order is null" : order.getUpphonenum() ));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return "failt";
	}

	private MultiMap parceString(String str){
		MultiMap map = new MultiMap();
		UrlEncoded.decodeTo(str, map, "utf-8");
		return map;
	}

	public String sign(JSONObject data ,String sysSecret){

		char[] s = JSONObject.toJSONString(data, SerializerFeature.WriteMapNullValue).toCharArray();
		Arrays.sort(s);
		String outputSignOriginalStr = new String(s) + sysSecret;
		String sign = MD5(outputSignOriginalStr);
		return sign;
	}

    /* 获取MD5加密
     *
	 * @param pwd
     *            需要加密的字符串
     * @return String字符串 加密后的字符串
     */
	public  String MD5(String pwd) {
		try {
			// 创建加密对象
			MessageDigest digest = MessageDigest.getInstance("md5");

			// 调用加密对象的方法，加密的动作已经完成
			byte[] bs = digest.digest(pwd.getBytes());
			// 第一步，将数据全部转换成正数：
			String hexString = "";
			for (byte b : bs) {
				// 第一步，将数据全部转换成正数：
				// 解释：为什么采用b&255
				/*
				 * b:它本来是一个byte类型的数据(1个字节) 255：是一个int类型的数据(4个字节)
				 * byte类型的数据与int类型的数据进行运算，会自动类型提升为int类型 eg: b: 1001 1100(原始数据)
				 * 运算时： b: 0000 0000 0000 0000 0000 0000 1001 1100 255: 0000
				 * 0000 0000 0000 0000 0000 1111 1111 结果：0000 0000 0000 0000
				 * 0000 0000 1001 1100 此时的temp是一个int类型的整数
				 */
				int temp = b & 255;
				// 第二步，将所有的数据转换成16进制的形式
				// 注意：转换的时候注意if正数>=0&&<16，那么如果使用Integer.toHexString()，可能会造成缺少位数
				// 因此，需要对temp进行判断
				if (temp < 16 && temp >= 0) {
					// 手动补上一个“0”
					hexString = hexString + "0" + Integer.toHexString(temp);
				} else {
					hexString = hexString + Integer.toHexString(temp);
				}
			}
			return hexString;
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * @return
	 */
	public void commitOrder(UpOrder order, UpShopInfo shop) {
		UpOrder product = this.upOrderService.findOrderProduct(order.getUporderuuid());
		if (product != null) {
			JSONObject data = new JSONObject();
			data.put("appid",shop.getAppId());
			data.put("timestamp", DateUtils.getNowDateToString());
			data.put("version","v1.0");
			data.put("sign_type","md5");
			try {
				JSONObject biz_content = new JSONObject();
				biz_content.put("product_id",order.getUpShopPro().getProductCode());
				biz_content.put("phone",order.getUpphonenum());
				biz_content.put("customer_order_no",order.getUporderuuid());
				data.put("biz_content",biz_content.toString());

				data.put("signature",sign(data,shop.getUpkey()));
				String res = HttpClient.post(shop.getOrderCommitAddress(),data.toString());
				logger.info("commithuarong_result:" + data +",phone:"+order.getUpphonenum()+",res:"+res);
				if (!StringUtils.isBlank(res)) {
					JSONObject jsonObject = JSONObject.parseObject(res);
					if(jsonObject.containsKey("code") && jsonObject.getString("code").equals("200")){
						upOrderService.updateUpOrderMsg(order,
								jsonObject.getJSONObject("result").getString("order_no"),
								jsonObject.getString("msg"));
					}else if (jsonObject.containsKey("code") && codesError.contains(jsonObject.getString("code"))) {
						order.setRemark(jsonObject.containsKey("msg") ?
								jsonObject.getString("msg") : Config.orderFailA);
						RechargeRest.failtUpOrder.add(order);
					}
				} else {
					upOrderService.commitFailt(order,  Config.commitFailt);
					logger.info("commithuarong_error" + order.getUpphonenum());
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private static Set<String> codesError = new HashSet<String>(){{
		add("1000");
		add("1001");
		add("1002");
		add("1003");
		add("1004");
		add("1005");
		add("1006");
		add("1007");
		add("1008");
		add("1009");
		add("1010");
		add("2001");
		add("1012");
		add("1013");
		add("1014");
		add("1015");
		add("2000");
		add("2002");
		add("2003");
		add("2004");
		//add("2005");
		add("2006");
		add("2007");
		add("2008");
		//add("3000");
		add("3001");
		add("3002");
		add("3003");
		add("3005");
		add("1016");
	}};


	/**
	 * @param order
	 * @param shop
	 */
	public void queryOrder(UpOrder order, UpShopInfo shop) {
		if(shop != null ){
			UpOrder product = upOrderService.findOrderProduct(order.getUporderuuid());
			if (product != null) {
				JSONObject data = new JSONObject();
				data.put("appid",shop.getAppId());
				data.put("timestamp", DateUtils.getNowDateToString());
				data.put("version","v1.0");
				data.put("sign_type","md5");
				try {

					JSONObject biz_content = new JSONObject();
					biz_content.put("order_month",DateUtils.toShortDateYYYYMonth(order.getCreatetime()));
					biz_content.put("customer_order_no",order.getUporderuuid());
					data.put("biz_content",biz_content.toString());

					data.put("signature",sign(data,shop.getUpkey()));
					String res = HttpClient.post(shop.getOrderStatusAddress(),data.toString());
					logger.info("queryhuarong:"+res+"data:"+data+",phone:"+product.getUpphonenum());
					if(res != null){
						JSONObject jsonObject = new JSONObject();
						if(jsonObject.containsKey("code") && jsonObject.getString("code").equals("200")){
							UpOrder orderproduct = upOrderService.findById(order.getUporderuuid());
							if(jsonObject.getJSONObject("result").getString("order_status").equals("success") &&
									orderproduct != null && orderproduct.getStatus() == Config.status[0] ){
								orderproduct.setRemark( jsonObject.getString("msg"));
								RechargeRest.successUpOrder.add(orderproduct);
							}else if((
									jsonObject.containsKey("result") && jsonObject.getJSONObject("result").getString("order_status").equals("fail")) &&
									orderproduct != null && orderproduct.getStatus() == Config.status[0] ){
								orderproduct.setRemark(jsonObject.getString("msg"));
								RechargeRest.failtUpOrder.add(orderproduct);
							}
						}
					}else{
						logger.info("queryhuarong order failt:"+order.getUpphonenum());
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}else{
			logger.info("queryhuarong order failt:"+order.getUpphonenum());
		}
	}


}
